package cn.bluedot.tea.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

public class DataBackupAndReductionUtil {

	private static String userName;
	private static String password;
	private static String hostIP;
	private static String databaseName;

	static {
		InputStream in = DataBackupAndReductionUtil.class.getClassLoader().getResourceAsStream("db.properties");
		Properties prop = new Properties();
		try {
			prop.load(in);
		} catch (IOException e) {
			System.err.println("db.properties 加载失败");
		}

		userName = prop.getProperty("jdbc.username");
		password = prop.getProperty("jdbc.password");
		String url = prop.getProperty("jdbc.url");
		hostIP = url.substring(url.indexOf("//") + 2, url.lastIndexOf('/') - 5);
		databaseName = url.substring(url.lastIndexOf('/') + 1, url.indexOf('?'));
	}

	/**
	 * 数据备份
	 * 
	 * @param tableNames 被备份的数据表的表名
	 * @param folderName 存放的文件夹的名称
	 */
	public static void dataBackup(List<String> tableNames, String savePath) {
		for (String fileName : tableNames) {
			backup(hostIP, userName, password, savePath, fileName, databaseName);
		}
	}

	public static void dataReduction(String folderPath) throws Exception {
		dataReduction(getAllFileName(folderPath), folderPath);
	}

	/**
	 * 数据还原
	 * 
	 * @param tableNames 被还原的数据库表的名字
	 * @param folderName 存放的文件夹的名称
	 * @throws Exception
	 */
	private static void dataReduction(List<String> tableNames, String folderPath) throws Exception {
		for (String tableName : tableNames) {
			restore(folderPath + "/" + tableName, hostIP, databaseName, userName, password);
		}
	}

	/**
	 * 递归获取文件夹内所有文件的名称
	 * 
	 * @param path
	 * @return
	 */
	private static List<String> getAllFileName(String path) {
		List<String> fileName = new ArrayList<String>();
		File file = new File(path);
		File[] files = file.listFiles();
		if(files != null) {
			String[] names = file.list();
			if (names != null)
				fileName.addAll(Arrays.asList(names));
			for (File a : files) {
				if (a.isDirectory()) {
					fileName.addAll(getAllFileName(a.getAbsolutePath()));
				}
			}
			return fileName;
		}else {
			throw new RuntimeException("没有用来备份的sql文件");
		}
	}

	/**
	 * @param hostIP       ip地址，可以是本机也可以是远程
	 * @param userName     数据库的用户名
	 * @param password     数据库的密码
	 * @param savePath     备份的路径
	 * @param fileName     备份的文件名
	 * @param databaseName 需要备份的数据库的名称
	 * @return
	 */
	private static boolean backup(String hostIP, String userName, String password, String savePath, String fileName,
			String databaseName) {
		File saveFile = new File(savePath);
		if (!saveFile.exists()) {// 如果目录不存在
			saveFile.mkdirs();// 创建文件夹
		}
		if (!savePath.endsWith(File.separator)) {
			savePath = savePath + File.separator;
		}

		// 拼接命令行的命令
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append("mysqldump").append(" --opt").append(" -h").append(hostIP);
		stringBuilder.append(" --user=").append(userName).append(" --password=").append(password)
				.append(" --lock-all-tables=true");
		stringBuilder.append(" --result-file=").append(savePath + fileName + ".sql")
				.append(" --default-character-set=utf8 ").append(databaseName).append(" " + fileName);
		try {
			// 调用外部执行exe文件的javaAPI
			Process process = Runtime.getRuntime().exec(stringBuilder.toString());
			if (process.waitFor() == 0) {// 0 表示线程正常终止。
				return true;
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * @param filepath 数据库备份的脚本路径
	 * @param ip       IP地址
	 * @param database 数据库名称
	 * @param userName 用户名
	 * @param password 密码
	 * @return
	 * @throws IOException
	 */
	private static boolean restore(String filepath, String ip, String database, String userName, String password)
			throws IOException {
		String stmt1 = "mysqladmin -h" + ip + " -u" + userName + " -p" + password + " create " + database;

		String stmt2 = "mysql -h" + ip + " -u" + userName + " -p" + password + " " + database + " < " + filepath;

		String[] cmd = { "cmd", "/c", stmt2 };

		try {
			Runtime.getRuntime().exec(stmt1);
			Runtime.getRuntime().exec(cmd);
			System.out.println("数据已从 " + filepath + " 导入到数据库中");
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

}
